package com.zd.server.sftpserver.sftp;

import org.apache.sshd.common.file.virtualfs.VirtualFileSystemFactory;
import org.apache.sshd.server.SshServer;
import org.apache.sshd.server.auth.AsyncAuthException;
import org.apache.sshd.server.auth.password.PasswordAuthenticator;
import org.apache.sshd.server.auth.password.PasswordChangeRequiredException;
import org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider;
import org.apache.sshd.server.session.ServerSession;
import org.apache.sshd.sftp.server.SftpSubsystemFactory;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Paths;
import java.util.Collections;
import java.util.concurrent.ConcurrentHashMap;

public class SftpServer {
    private final ConcurrentHashMap<String, SftpUser> users = new ConcurrentHashMap<>();
    private final SshServer sshd;
    public SftpServer(String host,Integer port,String generatorHostKeyPath) {
        SshServer sshd = SshServer.setUpDefaultServer();
        sshd.setPort(port);
        sshd.setHost(host);
        SftpSubsystemFactory factory = new SftpSubsystemFactory.Builder().build();
        sshd.setSubsystemFactories(Collections.singletonList(factory));
        sshd.setPasswordAuthenticator(new PasswordAuthenticator() {
            @Override
            public boolean authenticate(String userName, String password, ServerSession serverSession) throws PasswordChangeRequiredException, AsyncAuthException {
                if(StringUtils.hasText(userName) && StringUtils.hasText(password)){
                    if (users.containsKey(userName)) {
                        SftpUser user = users.get(userName);
                        if (user.getPassword().equals(password)) {
                            sshd.setFileSystemFactory(new VirtualFileSystemFactory(Paths.get(user.getHomeDirectory())));
                            return true;
                        }
                    }
                }
                return false;
            }

        });

        sshd.setKeyPairProvider (new SimpleGeneratorHostKeyProvider(FileSystems.getDefault().getPath(generatorHostKeyPath)));
        this.sshd = sshd;
    }
    public void start() throws IOException {
        sshd.start();
    }
    public void stop() throws IOException {
        sshd.stop();
    }
    public void addUser(SftpUser user) {
        users.put(user.getUsername(), user);
    }
    public void removeUser(String userName) {
        if (StringUtils.hasText(userName)) {
            users.remove(userName);
        }
    }
    public SftpUser getUser(String userName) {
        return users.get(userName);
    }
    public ConcurrentHashMap<String, SftpUser> getUsers() {
        return users;
    }
    public SshServer getSshd() {
        return sshd;
    }

}
